﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Security;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Web.Security;
using System.Web.Routing;
using TBM.Core;
using TBM.Tools;
using System.Text.RegularExpressions;

namespace TBM.Controllers
{
    public class MasterController : Controller
    {
        private bool _isAjaxRequest = false;
        protected SqlCommand cmd = new SqlCommand();
        protected Models.User CurrUser;
        protected bool IsAjaxRequest
        {
            get
            {
                return _isAjaxRequest;
            }
        }

        /// <summary>
        /// 设置是否为Ajax请求
        /// </summary>
        /// <param name="isAjaxRequest"></param>
        protected void SetAjaxRequest(bool isAjaxRequest)
        {
            _isAjaxRequest = isAjaxRequest;
        }

        public MasterController()
        {
            cmd.Connection = new SqlConnection(Config.ConnectionString);
            cmd.Connection.Open();

        }

        protected override void Dispose(bool disposing)
        {
            if (cmd.Connection != null && cmd.Connection.State != ConnectionState.Closed)
            {
                cmd.Connection.Close();
            }

            base.Dispose(disposing);
        }

        protected override void Initialize(RequestContext requestContext)
        {
            base.Initialize(requestContext);

            HttpRequestBase request = requestContext.HttpContext.Request;
            string uid = requestContext.HttpContext.User.Identity.Name;

            InitMenuCache(uid);

            string path = request.Path;
            string pageBar;
            string pageTitle;
            string pageSubTitle;

            if (path.Length == 0 || path[path.Length - 1] != '/')
            {
                path += "/";
            }

            ViewBag.MainMenu = GetMenu(path, out pageBar, out pageTitle, out pageSubTitle);
            ViewBag.PageBarNav = pageBar;
            ViewBag.PageTitle = pageTitle;
            ViewBag.PageSubTitle = pageSubTitle;

            _isAjaxRequest = request["ajax"] != null && Convert.ToBoolean(request["ajax"]);

            CurrUser = HttpRuntime.Cache.Get("User") as Models.User;
            
            if (CurrUser == null)
            {
                cmd.CommandText = @"select 
	                                    UID, 
	                                    (select 
                                                case ROW_NUMBER() over(order by G.GID) 
                                                    when 1 then '' else ', ' end + 
                                                    G.GroupName as 'text()' 
                                                from 
                                                    dbo.MemberShip as M inner join dbo.Groups as G on M.GID = G.GID 
                                                where M.UID = U.UID for xml path('')) as Groups, Password,
	                                    FirstName, LastName, PicUrl, Email, Phone, QQ, RegisterDate, IsActive, Memo, CNName 
                                    from dbo.Users as U where UID = @UID";
                cmd.CommandType = CommandType.Text;
                cmd.Parameters.Clear();
                cmd.Parameters.Add("@UID", SqlDbType.VarChar, 15);
                cmd.Parameters["@UID"].Value = uid;

                using (SqlDataReader dr = cmd.ExecuteReader())
                {
                    dr.Read();
                    CurrUser = new Models.User
                    {
                        UID = dr["UID"].ToString(),
                        Groups = dr["Groups"].ToString(),
                        Password = dr["Password"].ToString(),
                        FirstName = dr["FirstName"].ToString(),
                        LastName = dr["LastName"].ToString(),
                        PicUrl = dr["PicUrl"].ToString(),
                        Email = dr["Email"].ToString(),
                        Phone = dr["Phone"].ToString(),
                        QQ = dr["QQ"].ToString(),
                        RegisterDate = Convert.ToDateTime(dr["RegisterDate"]),
                        IsActive = (bool)dr["IsActive"],
                        Memo = dr["Memo"].ToString(),
                        CNName = (bool)dr["CNName"]
                    };
                }

                HttpRuntime.Cache.Insert("User", CurrUser);
            }

            ViewBag.CurrUser = CurrUser;

            cmd.CommandText = "p_GetTopOfInbox";
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Clear();
            cmd.Parameters.Add("@Own", SqlDbType.VarChar, 15);
            cmd.Parameters["@Own"].Value = CurrUser.UID;
            List<Models.Mail> mails = new List<Models.Mail>();
            Regex regGetTags = new Regex("<[^>]+>", RegexOptions.Multiline);

            using (SqlDataReader dr = cmd.ExecuteReader())
            {
                while (dr.Read())
                {
                    string context = regGetTags.Replace(dr["Context"].ToString(), "");

                    if (context.Length > 100)
                    {
                        context = context.Substring(0, 100) + "...";
                    }

                    mails.Add(new Models.Mail
                    {
                        ID = (long)dr["ID"],
                        MailFrom = new Models.UserListItem
                        {
                            FullName = dr["FullName"].ToString(),
                            PicUrl = dr["PicUrl"] != DBNull.Value ? dr["PicUrl"].ToString() + "small.png?" + DateTime.Now.Ticks : Core.Config.DefaultPic
                        },
                        MarkRead = (bool)dr["MarkRead"],
                        Context = context,
                        CreateDate = Convert.ToDateTime(dr["CreateDate"])
                    });
                }
            }

            ViewBag.Mails = mails;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="UID"></param>
        public void InitMenuCache(string UID)
        {

            // 加载菜单信息
            if (HttpRuntime.Cache.Get("PageList") == null)
            {
                List<TBM.Models.MainMenu> pageList = new List<Models.MainMenu>();
                cmd.CommandText = "p_PageList";
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Clear();
                cmd.Parameters.Add("@UID", SqlDbType.VarChar, 15);
                cmd.Parameters["@UID"].Value = UID;

                using (SqlDataReader dr = cmd.ExecuteReader())
                {
                    while (dr.Read())
                    {
                        pageList.Add(new Models.MainMenu
                        {
                            ID = (int)dr["ID"],
                            PID = (int)dr["PID"],
                            PageName = dr["PageName"].ToString(),
                            SubTitle = dr["SubTitle"].ToString(),
                            URL = dr["URL"].ToString(),
                            Icon = dr["Icon"].ToString(),
                            IsShow = (bool)dr["IsShow"],
                            Descr = dr["Descr"].ToString(),
                            Sort = (int)dr["Sort"]
                        });
                    }

                    HttpRuntime.Cache.Insert("PageList", pageList);
                }

                List<TBM.Models.MainMenu> mainMenu = new List<TBM.Models.MainMenu>();

                foreach (TBM.Models.MainMenu item in pageList.Where(a => a.PID == 0))
                {
                    mainMenu.Add(item);
                    AddSubMenu(item, pageList);
                }

                HttpRuntime.Cache.Insert("MainMenu", mainMenu);
            }
        }

        /// <summary>
        /// 添加子菜单
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="pageList"></param>
        private void AddSubMenu(Models.MainMenu parent, List<TBM.Models.MainMenu> pageList)
        {
            List<TBM.Models.MainMenu> subList = pageList.Where(a => a.PID == parent.ID).ToList();

            if (subList.Count == 0) return;

            foreach (TBM.Models.MainMenu item in subList)
            {
                AddSubMenu(item, pageList);
            }

            parent.SubMenu = subList;
        }


        /// <summary>
        /// 生成菜单
        /// 支持多层
        /// </summary>
        /// <param name="currentPageID">当前页面ID</param>
        /// <returns></returns>
        public string GetMenu(string path, out string pageBar, out string title, out string subTitle)
        {
            List<TBM.Models.MainMenu> pageList = HttpRuntime.Cache.Get("PageList") as List<TBM.Models.MainMenu>;
            List<TBM.Models.MainMenu> mainMenu = HttpRuntime.Cache.Get("MainMenu") as List<TBM.Models.MainMenu>;
            pageBar = "";
            title = "";
            subTitle = "";
            path = path.ToLower();

            if (pageList == null)
            {
                return "";
            }

            List<TBM.Models.MainMenu> pageids = new List<Models.MainMenu>();
            GetBreadNavNodes(pageList.Where(a => a.URL == path).FirstOrDefault(), pageids, pageList);

            StringBuilder menu = new StringBuilder("<ul class=\"page-sidebar-menu page-sidebar-menu-hover-submenu\" data-keep-expanded=\"false\" data-auto-scroll=\"true\" data-slide-speed=\"200\">");

            bool firstItem = true;
            foreach (TBM.Models.MainMenu item in mainMenu)
            {
                bool isParentActived = pageids.Where(a => a.ID == item.ID).Count() > 0;
                if (firstItem)
                {
                    menu.AppendLine(String.Format("<li class=\"start{0}\">", isParentActived ? " active" : ""));
                    firstItem = false;
                }
                else
                {
                    menu.AppendLine(String.Format("<li{0}>", isParentActived ? " class=\"active\"" : ""));
                }
                menu.AppendFormat("<a href=\"{0}\">", item.URL);
                menu.AppendFormat("<i{0}></i>", !String.IsNullOrEmpty(item.Icon) ? String.Format(" class=\"{0}\"", item.Icon) : "");
                menu.AppendFormat("<span class=\"title\">{0}</span>", item.PageName);
                if (isParentActived) menu.AppendLine("<span class=\"selected\"></span>");
                if (item.SubMenu != null) menu.AppendFormat("<span class=\"arrow{0}\"></span>", isParentActived ? " open" : "");
                menu.Append("</a>");
                menu.AppendLine(GetSubMenu(item, pageids));
                menu.AppendLine("</li>");
            }

            StringBuilder pageBarNav = new StringBuilder("<ul class=\"page-breadcrumb\">");

            pageBarNav.AppendLine(@"<li>
                                        <i class=""fa fa-home""></i>
                                        <a href=""/"">首页</a>
                                        <i class=""fa fa-angle-right""></i>
                                    </li>");
            
            for (int idx = pageids.Count() - 1; idx >= 0; idx--)
            {
                TBM.Models.MainMenu item = pageids[idx];
                pageBarNav.AppendLine("<li>");

                if (idx > 0)
                {
                    pageBarNav.AppendFormat("<a href=\"{0}\">{1}</a>", item.URL, item.PageName);
                    pageBarNav.Append("<i class=\"fa fa-angle-right\"></i>");
                }
                else
                {
                    pageBarNav.AppendFormat("{0}", item.PageName);
                    title = item.PageName;
                    subTitle = item.SubTitle;
                }

                pageBarNav.AppendLine("</li>");
            }

            pageBarNav.AppendLine("</ul>");

            pageBar = pageBarNav.ToString();

            return menu.ToString();
        }

        /// <summary>
        /// 获取子菜单
        /// </summary>
        /// <param name="item"></param>
        /// <param name="pageids"></param>
        /// <returns></returns>
        private string GetSubMenu(TBM.Models.MainMenu item, List<TBM.Models.MainMenu> pageids)
        {
            StringBuilder menu = new StringBuilder();
            menu.AppendLine("<ul class=\"sub-menu\">");
            if (item.SubMenu != null)
            {
                foreach (TBM.Models.MainMenu sitem in item.SubMenu)
                {
                    bool isSubActived = pageids.Where(a => a.ID == sitem.ID).Count() > 0;
                    menu.AppendLine(String.Format("<li{0}>", isSubActived ? " class=\"active\"" : ""));
                    menu.AppendFormat("<a href=\"{0}\">", sitem.URL);
                    menu.AppendFormat("<i class=\"{0}\"></i>", sitem.Icon);
                    menu.Append(sitem.PageName);
                    menu.Append("<span class=\"arrow\"></span></a>");
                    menu.AppendLine(GetSubMenu(sitem, pageids));
                    menu.AppendLine("</li>");
                }
            }
            menu.AppendLine("</ul>");

            return menu.ToString();
        }

        /// <summary>
        /// 获取面包屑导航
        /// </summary>
        /// <param name="item"></param>
        /// <param name="pageids"></param>
        /// <param name="menu"></param>
        private void GetBreadNavNodes(TBM.Models.MainMenu item, List<TBM.Models.MainMenu> pageids, List<TBM.Models.MainMenu> menu)
        {
            if (item == null) return;
            pageids.Add(item);
            if (item.PID == 0) return;

            TBM.Models.MainMenu parentItem = menu.Where(a => a.ID == item.PID).FirstOrDefault();
            GetBreadNavNodes(parentItem, pageids, menu);
        }
    }
}
